package com.cy.aviator;

import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.function.FunctionUtils;
import com.googlecode.aviator.runtime.type.AviatorDouble;
import com.googlecode.aviator.runtime.type.AviatorObject;
import org.apache.commons.lang3.StringUtils;
import org.testng.annotations.Test;

import java.io.IOException;
import java.util.Map;

//https://www.yuque.com/boyan-avfmj/aviatorscript
public class DemoWithAviatorShare {


    @Test(description = "基础表达式执行")
    public void t1() {
        // 返回 419
        System.out.println(AviatorEvaluator.getInstance().execute("4*100 + ( 1*10 + 9)"));

        // 返回 hello world
        System.out.println(AviatorEvaluator.execute("'hello' + ' world'"));

        // 返回 ture
        System.out.println(AviatorEvaluator.execute("100 > 80 && 30 < 40"));

        // 三元表达式，返回 30
        System.out.println(AviatorEvaluator.execute("100 > 80 ? 30 : 40"));

        // 正则表达式，正则表达式放在//之间，返回 true
        System.out.println(AviatorEvaluator.execute("'hello' =~ /[\\w]+/"));
    }


    @Test(description = "变量入参")
    public void t3() {
        Expression compiledExp = AviatorEvaluator.compile("a + b > 100", true);
        System.out.println(compiledExp.execute(compiledExp.newEnv("a", 50, "b", 49)));

        System.out.println(AviatorEvaluator.compile("name != nil ? ('hello, ' + name):'who are u?'").execute());

        System.out.println(AviatorEvaluator.compile("name != nil ? ('hello, ' + name):'who are u?'").execute(compiledExp.newEnv("name", "Cy")));
    }

    @Test(description = "使用内置函数")
    public void t4() {
        // 返回4
        System.out.println(AviatorEvaluator.execute("math.round(4.3)"));

        // 返回5
        System.out.println(AviatorEvaluator.execute("string.length('hello')"));

        // 返回一个ArrayList：[1,2,3]
        Object res = AviatorEvaluator.execute("seq.list(1,2,3)");
        System.out.println(res.getClass());
        System.out.println(res);
    }

    @Test(description = "自定义方法")
    public void t5() {
        AviatorEvaluator.addFunction(new CyAddFunction());
        // 3.0
        System.out.println(AviatorEvaluator.execute("cy_add(1, 2)"));
        // 103.0
        System.out.println(AviatorEvaluator.execute("cy_add(cy_add(1, 2), 100)"));
    }

    class CyAddFunction extends AbstractFunction {
        public String getName() {
            return "cy_add";
        }

        @Override
        public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
            Number left = FunctionUtils.getNumberValue(arg1, env);
            Number right = FunctionUtils.getNumberValue(arg2, env);
            return new AviatorDouble(left.doubleValue() + right.doubleValue());
        }
    }

    @Test(description = "调用 Java 静态方法")
    public void t6() throws NoSuchMethodException, IllegalAccessException {
        AviatorEvaluator.addStaticFunctions("cyStringUtils", StringUtils.class);
        System.out.println(AviatorEvaluator.execute("cyStringUtils.isBlank(a)"));
    }

    @Test(description = "变量作用域  是否写let的含义")
    public void t7() throws IOException {
        AviatorEvaluator.getInstance().compileScript("aviator/java1.av").execute();
    }
}
